﻿#define _CRT_SECURE_NO_WARNINGS 1
#pragma warning(disable:6031)
#include<stdio.h>
/*int main()
{
    union
    {
        short k;
        char i[2];
    }*s, a;
    s = &a;
    s->i[0] = 0x39;
    s->i[1] = 0x38;
    printf("%x\n", a.k);
    return 0;
}*///打印从高位开始打；
//程序环境与预处理
//第1种是翻译环境，在这个环境中源代码被转换为可执行的机器指令。第2种是执行环境，它用于实际执行代码;
//c语言代码是文本信息，计算机不能直接理解，依赖翻译环境翻译成二进制指令，二进制指令放在可执行程序里，依赖执行环境执行；
//#include<stdio.h>
//extern int add(int, int);
//int main()
//{
//	int a = 10;
//	int b = 20;
//	int c = add(a, b);
//	printf("%d\n", c);
//	return 0;
//}

//编译：预编译；编译；汇编；

//预编译：注释的删除；#include头文件的包含；#define的替换；  这些都是文本操作；
//#include 和#define 都是预处理指令，所有的预处理指令都是在预编译阶段处理的；

//编译：把C语言代码翻译成汇编指令； 语法分析，语义分析，词法分析，符号汇总；

//汇编：生成二进制指令，全是汇编代码，把汇编代码翻译成二进制指令，生成目标文件；
//形成符号表；

//test.o(目标文件)和可执行程序都是按照elf形式存储的 （分段的形式）
//链接；
//1.合并段表；2.符号表的合并和重定位；

//链接完成生成可执行程序；

//《程序员的自我修养》

//#include<stdio.h>
//
//struct tagPIM
//{
//    unsigned char ucPim1;
//    unsigned char ucData0 : 1;
//    unsigned char ucData1 : 2;
//    unsigned char ucData2 : 3;
//};
//struct _Record_Struct
//{
//    unsigned char Env_Alarm_ID : 4;
//    unsigned char Para1 : 2;
//    unsigned char state;
//    unsigned char avail : 1;
//};
//int main()
//{
//	printf("%d\n", sizeof(struct _Record_Struct));
//	return 0;
//}

//#include <stdio.h>      /* printf, fgets */
//#include <stdlib.h>     /* atoi */
//
//int main()
//{
//    int i;
//    char buffer[256];
//    printf("Enter a number: ");
//    fgets(buffer, 256, stdin);
//    i = atoi(buffer);
//    printf("The value entered is %d. Its double is %d.\n", i, i * 2);
//    return 0;
//}

//
//#include<stdio.h>
//int main()
//{
//    int arr[] = { 1,2,3,4,5,1,2,3,4,6 };
//    int arr2[10] = {0};
//    int sz = sizeof(arr) / sizeof(arr[0]);
//    int i = 0;
//    int j = 0;
//    for (i = 0;i < sz;i++)
//    {
//        arr2[i] = arr[i];
//    }
//   
// 
//    for (i = 0;i < sz;i++)
//    {
//        for (j = i + 1;j < sz;j++)
//        {
//            int flag = 0;
//            if (arr2[i] == arr2[j])
//            {
//                arr2[i] = 0;
//                arr2[j] = 0;
//            }
//           
//        }
//    }
//    for (i = 0;i < sz;i++)
//    {
//        if (arr2[i] != 0)
//        {
//            printf("%d ", arr2[i]);
//        }
//    }
//    return 0;
//}

//#include<stdio.h>
//int main()
//{
//    printf("%s\n", __FILE__);
//    printf("%d\n", __LINE__);//这些预定义符号在预处理的时候被处理；
//    printf("%s\n", __DATE__);
//    printf("%s\n", __TIME__);
//   /* printf("%s\n", __STDC__);*///这里不支持ansic
//    return 0;
//}

//#define 换行时要在行末加\ ,转义回车，使其还是一行；
//#define 定义常量不要加 ；
//#include<stdio.h>
//#define MAX 1000
//#define reg register 
////为 register这个关键字，创建一个简短的名字#define do_forever for(;;)     //用更形象的符号来替换一种实现
//#define CASE break;case  //在写case语句的时候自动把 break写上。把CASE 定义为 break;case(尽量不用)；
//#define doforever for( ; ; )
//int main()
//{
//    printf("%d\n", MAX);
//    doforever
//    {
//
//    }
//    return 0;
//}
//#include<stdio.h>
//#define DEBUGPRINT printf("file:%s\tline:%d\tdate:%s\
//                        \ttime:%s\n",__FILE__,__LINE__,\
//                         __DATE__,__TIME__ )
//int main()
//{
//    DEBUGPRINT;
//    return 0;
//}

//#define MAX(x,y)/*MAX后面的左括号前不能加空格，否则会认为空格后面的内容是MAX的定义宏*/ ((x)>(y)?(x):(y))  //宏有参数  //x，y要加括号
//#include<stdio.h>//后面的宏参数必须要加括号，因为x、y有可能是表达式，运算符会出现问题；整体要加括号，因为算出结果有可能与外部运算；
////因为宏运算是替代规则；
///*
//1. 在调用宏时，首先对参数进行检查，看看是否包含任何由#define定义的符号。如果是，它们首先
//被替换。
//2. 替换文本随后被插入到程序中原来文本的位置。对于宏，参数名被他们的值替换。
//3. 最后，再次对结果文件进行扫描，看看它是否包含任何由#define定义的符号。如果是，就重复上
//述处理过程。
//*/
//int main()
//{
//    int a = 2;
//    int b = 2;
//    int c = MAX(a, b);//不用运算，直接进去替代；
//    printf("%d\n", c);
//    return 0;
//}

//#和##

//如何把参数插入到字符串中？

//#define print(x,y) printf("the value of "#x" ="y"\n",x)//这样就可以改变字符串中 的参数
//int main()//#可以把宏的参数以字符串的形式插入宏定义的字符串中；把一个宏参数变成对应的字符串；#x把x变成相应的字符串，y本身是字符串，不用#y
//{
//    //printf("hahaha""\n");//可以这样写，打印两个字符串；
//    int a = 3;
//    print(a, "%d");
//    int b = 3;
//    print(b, "%d");
//    float c = 3.2f;
//    print(c, "%f");
//
//    return 0;
//}
/*
##可以把位于它两边的符号合成一个符号。
它允许宏定义从分离的文本片段创建标识符。
*/ 
//# ##只能在宏里这样用；

//当宏参数在宏的定义中出现超过一次的时候，如果参数带有副作用，那么你在使用这个宏的时候就可能出现危险，导致不可预测的后果。副作用就是表达式求值的时候出现的永久性效果。
//#define MAX(a, b) ( (a) > (b) ? (a) : (b) )
//int main()
//{
//    int x = 5;
//    int y = 8;
//    int z = MAX(x++, y++);
//    int z = ((x++) > (y++) ? (x++) : (y++));//x>y,x先++，y先++，x赋给z，x还要++；
//    printf("x=%d y=%d z=%d\n", x, y, z);
//    return 0;
//}


//宏和函数对比

//宏有时候可以做函数做不到的事情。比如：宏的参数可以出现类型，但是函数做不到。
#define MALLOC(num, type) (type *)malloc(num * sizeof(type))
int main()
{
    int* abc=MALLOC(126, int);
    return 0;
}
//宏用来解决相对简单的运算；